home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 145
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin
/
tools
/
sharp
/
sxwork3.lzh
/
サンプル応用編
/
イメージ編集
/
GISUBWIN.C
< prev
next >
Wrap
Text File
|
1994-03-10
|
19KB
|
548 lines
/******************************************************************************
* gisubwin.c: サブウィンドウの処理関数
******************************************************************************
* Workroom SX-68K Sample Program Copyright 1994 SHARP
*/
#include <stdio.h> /* sprintf()など */
#include <event.h> /* イベントマンを利用するときに必要 */
#include <sxgraph.h> /* グラフ系マネージャを利用するときに必要 */
#include <window.h> /* ウィンドウマンを利用するときに必要 */
#include <control.h> /* コントロールマンを利用するときに必要 */
#include <task.h> /* タスクマンを利用するときに必要 */
#include "gimage.h" /* このプログラム固有のヘッダファイル */
static Rect wsSize[SUBMAX] = { /* サブウィンドウサイズ */
{ 0, 0, TLSUB_H, TLSUB_V }, /* ツールウィンドウ */
{ 0, 0, PLSUB_H, PLSUB_V } /* 色選択ウィンドウ */
};
/******************************************************************************
* createSubwin(): サブウィンドウの作成
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* 戻り値: BOOLEAN = TRUE: 作成成功
* = FALSE: 作成失敗(終了)
*/
BOOLEAN createSubwin(ComVal *pcv)
{
int i;
Rect rc;
static Point wsPos[SUBMAX] = { /* サブウィンドウの表示位置 */
{ TLPOS_X, TLPOS_Y }, /* ツールウィンドウ */
{ PLPOS_X, PLPOS_Y } /* 色選択ウィンドウ */
};
for (i = 0; i < SUBMAX; i++) {
/* リージョンハンドルを確保する */
pcv->subRgnHdl[i] = GMNewRgn();
if (pcv->subRgnHdl[i] == NULL)
return FALSE; /* 失敗したのでFALSEを返す */
/* サブウィンドウの外枠(リージョン)を設定する */
rc = wsSize[i];
rc.d.right--;
rc.d.bottom--;
GMRectRgn(pcv->subRgnHdl[i], &rc);
rc.d.left += 4;
rc.d.top += 4;
rc.d.right++;
rc.d.bottom++;
GMOrRectRgn(pcv->subRgnHdl[i], pcv->subRgnHdl[i], &rc);
rc = wsSize[i];
GMSlideRect(&rc, wsPos[i].x_y);
TSAdjustRect(&rc, &rc, 16); /* 表示位置を補正する */
GMSlideRgn(pcv->subRgnHdl[i], rc.l.l_t);
/* サブウィンドウがオープンできたか? */
if (!openSubwin(pcv, i))
return FALSE; /* 失敗したのでFALSEを返す */
}
return TRUE; /* 成功したのでTRUEを返す */
}
/******************************************************************************
* openSubwin(): サブウィンドウのオープン
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* int num サブウィンドウの番号
* 戻り値: BOOLEAN = TRUE: オープン成功
* = FALSE: オープン失敗
*/
BOOLEAN openSubwin(ComVal *pcv, int num)
{
pcv->subwinPtr[num] = WSOpen( /* サブウィンドウをオープンする */
NULL, /* サブウィンドウポインタを確保する */
pcv->subRgnHdl[num], /* リージョンハンドル */
(unsigned long) num + 32); /* プライオリティ値(通常は32以上)*/
if (pcv->subwinPtr[num] == NULL)
return FALSE; /* 失敗したのでFALSEを返す */
if (num == TOOL) /* ツールウィンドウか? */
if (!createSubControl(pcv)) /* コントロールを作成する */
return FALSE; /* 失敗したのでFALSEを返す */
/* サブウィンドウをカレントグラフにする */
GMSetGraph(&pcv->subwinPtr[num]->win.graph);
GMPenMode(G_PSET); /* ペンモードをPSETにする */
GMForeColor(G_BLACK); /* フォアグラウンドカラーを黒にする */
/* バックグラウンドカラーをライトグレーにする */
GMBackColor(G_LGRAY);
GMFontMode(G_PSET); /* フォントモードをPSETにする */
/* タスクIDの上位ワードにサブウィンドウの通し番号を入れる(0以外) */
pcv->subwinPtr[num]->win.taskID = LONGWORD(num + 1, TSGetID());
return TRUE; /* 成功したのでTRUEを返す */
}
/******************************************************************************
* closeSubwin(): サブウィンドウのクローズ
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* int num サブウィンドウの番号
*/
void closeSubwin(ComVal *pcv, int num)
{
if (num == TOOL) /* ツールウィンドウか? */
/* コントロールを廃棄する */
CMKill(&pcv->subwinPtr[TOOL]->win);
WSDispose(pcv->subwinPtr[num]); /* サブウィンドウをクローズする */
}
/******************************************************************************
* createSubControl(): サブウィンドウ内のコントロールの作成
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* 戻り値: BOOLEAN = TRUE: 作成成功
* = FALSE: 作成失敗(終了)
*/
BOOLEAN createSubControl(ComVal *pcv)
{
int penX = pcv->penSize.p.x;
static Rect bounds = { /* 数値調整ボタンの位置と大きさ */
ADJ_X, ADJ_Y, ADJ_X + ADJBTN_H + 6 * 3 + 8, ADJ_Y + ADJBTN_V
};
/* 数値調整ボタンのタイトルを作成する */
sprintf((char *) pcv->adjBtnTtl, "\x03%3d", penX);
/* 数値調整ボタンを作成する */
pcv->adjBtnHdl = CMOpen(&pcv->subwinPtr[TOOL]->win, &bounds,
pcv->adjBtnTtl, TRUE, penX, 1, 50, CI_ADJBTN << 4, 0);
if (pcv->adjBtnHdl == NULL)
return FALSE; /* 失敗したのでFALSEを返す */
return TRUE; /* 成功したのでTRUEを返す */
}
/******************************************************************************
* checkSubControl(): サブウィンドウ内のコントロールのチェック
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
*/
void checkSubControl(ComVal *pcv)
{
int partCode; /* コントロールのパートコード */
Control **ctrlHdl; /* コントロールハンドル */
/* マウスのボタンが押されている間、コントロールの各種処理をシステムに
任せて、コントロールハンドルとボタンが押された、または離された場所
のパートコードを取得する */
partCode = SXCallCtrlM(&pcv->subwinPtr[TOOL]->win, &pcv->event, 0, 0, NULL, &ctrlHdl);
/* 数値調整ボタンで、ハンドルが一致したか? */
if ((partCode == C_INDEC || partCode == C_ININC)
&& ctrlHdl == pcv->adjBtnHdl) {
/* 数値調整ボタンのリピート処理を行う */
repeatAdjBtn(pcv, partCode);
/* ペン幅をワークに設定する */
pcv->penSize.p.x = CMValueGet(pcv->adjBtnHdl);
pcv->penSize.p.y = pcv->penSize.p.x;
}
}
/******************************************************************************
* msLDownSubwin(): サブウィンドウのマウスレフトダウンイベント処理
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* int num サブウィンドウの番号
* 戻り値: int サブウィンドウのパートコード
* 注釈:
* サブウィンドウ上でマウスの左ボタンが押された場合の処理を行う。サポート
* される処理は、サブウィンドウの移動、クローズボタンの強調表示で、マウス
* のボタンが押された、または離された場所のパートコードを取得します。
*/
int msLDownSubwin(ComVal *pcv, int num)
{
LPoint lpt;
Rect rc;
static Rect wsInside[SUBMAX] = { /* サブウィンドウの内側 */
/* ツールウィンドウ */
{ WS_INSIDE_X, WS_INSIDE_Y, TLSUB_H - 2, TLSUB_V - 2 },
/* 色選択ウィンドウ */
{ WS_INSIDE_X, WS_INSIDE_Y, PLSUB_H - 2, PLSUB_V - 2 }
};
calcPctBtn(num, CLOSE, &rc); /* クローズボタンの位置を求める */
/* イベント発生時のポインタ座標をローカル座標系に変換する */
lpt = GMGlobalToLocal(pcv->event.ev.where.x_y);
if (GMPtInRect(&rc, lpt)) { /* クローズボタンが押されたか? */
if (checkPctBtn(pcv, num, CLOSE, lpt)) {
/* サブウィンドウを消去する */
WSDelist(pcv->subwinPtr[num]);
pcv->subActiveFlag[num] = FALSE;
return WS_INCLOSE;
}
/* サブウィンドウの内側か? */
} else if (GMPtInRect(&wsInside[num], lpt)) {
return WS_ININSIDE;
/* サブウィンドウのドラッグリージョン(内側でない)*/
} else {
dragSubwin(pcv, lpt, num); /* サブウィンドウをドラッグする */
return WS_INDRAG;
}
return 0;
}
/******************************************************************************
* dragSubwin(): サブウィンドウのドラッグ(移動)処理
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* LPoint lpt ポインタ座標(ローカル座標系)
* int num サブウィンドウの番号
*/
void dragSubwin(ComVal *pcv, LPoint lpt, int num)
{
Point pt, pt2, npt, dpt;
Rect rc;
rc = wsSize[num];
GMInvertRect(&rc, WS_RUBBERBAND); /* ラバーバンドを描画する */
pt.x_y = lpt;
/* サブウィンドウの左上座標からマウスの現在位置までの距離を計算する */
pt2.p.x = pcv->event.ev.where.p.x - (*pcv->subRgnHdl[num])->bounds.d.left;
pt2.p.y = pcv->event.ev.where.p.y - (*pcv->subRgnHdl[num])->bounds.d.top;
/* マウスの左ボタンが押されたままなら、ラバーバンドを移動する */
do {
npt.x_y = EMMSLoc(); /* マウスの現在位置を取得する */
if (npt.x_y != pt.x_y) { /* マウスが移動したか? */
/* ラバーバンドを消去する */
GMInvertRect(&rc, WS_RUBBERBAND);
/* 移動後のレクタングルを設定する */
dpt.p.x = npt.p.x - pt.p.x;
dpt.p.y = npt.p.y - pt.p.y;
GMSlideRect(&rc, dpt.x_y);
/* ラバーバンドを描画する */
GMInvertRect(&rc, WS_RUBBERBAND);
}
pt = npt;
} while (EMLStill()); /* 左ボタンが離されたら終わり */
GMInvertRect(&rc, WS_RUBBERBAND); /* ラバーバンドを消去する */
/* 左ボタンが離された位置がドラッグ開始位置と同じか? */
if (pt.x_y == lpt)
return; /* 同じ場合はこのまま */
/* 移動後のサブウィンドウの外枠(リージョン)を設定する */
pt.p.x -= pt2.p.x;
pt.p.y -= pt2.p.y;
GMSlideRgn(pcv->subRgnHdl[num], pt.x_y);
/* サブウィンドウの移動は、サブウィンドウを一度クローズして
新しいリージョンで再度オープンする */
closeSubwin(pcv, num); /* サブウィンドウをクローズする */
if (!openSubwin(pcv, num)) { /* サブウィンドウをオープンする */
/* サブウィンドウがオープンできなかったので、ドラッグは失敗 */
pcv->subActiveFlag[num] = FALSE;
pcv->errorCode = 5;
pcv->endFlag = TRUE; /* 終了フラグをセットする */
}
}
/******************************************************************************
* drawSubwin(): サブウィンドウの描画
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* int num サブウィンドウの番号
*/
void drawSubwin(ComVal *pcv, int num)
{
int i, lastAP, lastPM;
Rect rc;
/* サブウィンドウをテキストタイプでカレントグラフにする */
setGraph(pcv, num, G_TXT);
rc = wsSize[num];
/* サブウィンドウを描画する場合は、まず全体(全ページ)をクリアする */
lastAP = GMAPage(G_ALLPAGE); /* アクセスページを全ページにする */
/* ペンモードをバックグラウンドカラーにする */
lastPM = GMPenMode(G_BACK << 8 | G_PSET);
GMFillRect(&rc); /* サブウィンドウ内をクリアする */
GMPenMode(lastPM); /* ペンモードを元に戻す */
GMAPage(lastAP); /* アクセスページを元に戻す */
GMFrameRect(&rc); /* サブウィンドウの外枠を描画する */
rc.d.right--;
rc.d.bottom--;
GMFrameRect(&rc);
drawSubTitleBar(pcv, num); /* タイトルバーを描画する */
switch (num) {
case TOOL: /* ツールウィンドウ */
/* アクセスページを0~2ページにする */
GMAPage(G_PAGE0 | G_PAGE1 | G_PAGE2);
/* "ペン幅"を描画する */
GMShadowStrZ("ペン幅", LONGWORD(10, WS_INSIDE_Y + 6));
for (i = 0; i < 12; i++) {
/* ピクチャーボタンの位置を求める */
calcPctBtn(TOOL, i, &rc);
/* ピクチャーボタンを描画する */
GMPutRImg(*pcv->pctBtnImg[i], rc.l.l_t);
if (i == pcv->toolKind) /* 選択されているツールか? */
revFrameRect(&rc); /* フレームを反転する */
}
GMAPage(lastAP); /* アクセスページを元に戻す */
CMDraw(&pcv->subwinPtr[TOOL]->win); /* コントロールを描画する */
break;
case PALET: /* 色選択ウィンドウ */
for (i = 0; i < 16; i++) {
/* ピクチャーボタンの位置を求める */
calcPctBtn(PALET, i, &rc);
/* PAT4のデータなので、アクセスページを全ページにする */
GMAPage(G_ALLPAGE);
/* ピクチャーボタンを描画する */
GMPutRImg(*pcv->plBtnImg, rc.l.l_t);
GMAPage(lastAP); /* アクセスページを元に戻す */
if (i == pcv->paletNo) /* 選択されているパレットか? */
revFrameRect(&rc); /* フレームを反転する */
/* 色選択ウィンドウをグラフィックタイプでカレント
グラフにする */
setGraph(pcv, PALET, G_GRP);
/* グラフィックスクリーンをパレット番号で塗りつぶす */
GMForeColor(i);
/* カラー部分のレクタングルを求める */
GMInsetRect(&rc, LONGWORD(2, 2));
GMFillRect(&rc);
/* 色選択ウィンドウをテキストタイプでカレントグラフに
する */
setGraph(pcv, PALET, G_TXT);
/* フォアグラウンドカラーを元に戻す */
GMForeColor(G_BLACK);
}
break;
}
}
/******************************************************************************
* drawSubTitleBar(): サブウィンドウのタイトルの描画
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* int num サブウィンドウの番号
*/
void drawSubTitleBar(ComVal *pcv, int num)
{
int i;
Rect rc;
/* サブウィンドウのタイトルバーの描画情報 */
struct {
int color;
Rect rc;
} wsTitle[7] = {
{ G_DGRAY, { 1, 1, -2, 17 }},
{ G_WHITE, { 1, 1, 3, 16 }},
{ G_WHITE, { 3, 1, -2, 3 }},
{ G_DGRAY, { 2, 15, -2, 18 }},
{ G_BLACK, { -3, 2, -1, 17 }},
{ G_BLACK, { 1, 16, -3, 17 }},
{ G_BLACK, { 3, 15, -3, 16 }}
};
/* サブウィンドウのタイトルバーを描画する */
for (i = 0; i < 7; i++) {
GMForeColor(wsTitle[i].color);
if (wsTitle[i].rc.d.left < 0)
wsTitle[i].rc.d.left += wsSize[num].d.right;
if (wsTitle[i].rc.d.right < 0)
wsTitle[i].rc.d.right += wsSize[num].d.right;
GMFillRect(&wsTitle[i].rc);
}
GMForeColor(G_BLACK); /* フォアグラウンドカラーを元に戻す */
calcPctBtn(num, CLOSE, &rc); /* クローズボタンの位置を求める */
GMPutRImg(*pcv->pctBtnImg[12], rc.l.l_t); /* クローズボタンを描画する */
}
/******************************************************************************
* selectPctBtn(): ピクチャーボタンの選択
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* int num サブウィンドウの番号
* 戻り値: int ピクチャーボタンの番号(1~15)
* < 0: 選択なし
*/
void selectPctBtn(ComVal *pcv, int num)
{
int i, cnt, ono;
LPoint lpt;
Rect rc;
if (num == TOOL) { /* ツールウィンドウか? */
ono = pcv->toolKind;
cnt = 12;
} else { /* 色選択ウィンドウ */
ono = pcv->paletNo;
cnt = 16;
}
/* 入力座標をローカル座標系に変換する */
lpt = GMGlobalToLocal(pcv->event.ev.where.x_y);
/* 押された所がどの部分か調べる */
for (i = 0; i < cnt; i++) {
calcPctBtn(num, i, &rc); /* ピクチャーボタンの位置を求める */
if (GMPtInRect(&rc, lpt)) {
/* 前回と違うピクチャーボタンが選択されたか? */
if (i != ono && checkPctBtn(pcv, num, i, lpt)) {
if (num == TOOL) /* ツールウィンドウか? */
/* ツールを変更する */
pcv->toolKind = i;
else /* 色選択ウィンドウ */
/* パレットを変更する */
pcv->paletNo = i;
}
return;
}
}
}
/******************************************************************************
* calcPctBtn(): ピクチャーボタンの位置算出
******************************************************************************
* 引数: int num サブウィンドウの番号
* int no ピクチャーボタンの番号(0~15、CLOSE)
* Rect *prc 表示位置のレクタングルを格納するポインタ
*/
void calcPctBtn(int num, int no, Rect *prc)
{
Point pt;
/* クローズボタンのサイズ */
static Rect clsSize = { 0, 0, WS_CLOSE_W, WS_CLOSE_W };
/* その他のピクチャーボタンのサイズ */
static Rect pctSize = { 0, 0, 20, 20 };
if (no == CLOSE) { /* クローズボタンか? */
*prc = clsSize;
pt.x_y = LONGWORD(wsSize[num].d.right - WS_CLOSE_W - 4, 4);
} else { /* その他のピクチャーボタン */
*prc = pctSize;
switch (num) {
case TOOL: /* ツールウィンドウ */
pt.p.x = 10;
pt.p.y = WS_INSIDE_Y + 24;
if (no >= 6) {
no -= 6;
pt.p.y += 21;
}
break;
case PALET: /* 色選択ウィンドウ */
pt.p.x = 4;
pt.p.y = WS_INSIDE_Y + 2;
if (no >= 8) {
no -= 8;
pt.p.y += 21;
}
break;
}
pt.p.x += no * 20;
}
GMSlideRect(prc, pt.x_y);
}
/******************************************************************************
* checkPctBtn(): ピクチャーボタンのチェック
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* int num サブウィンドウの番号
* int no ピクチャーボタンの番号(0~15、CLOSE)
* LPoint lpt ポインタ座標(ローカル座標系)
* 戻り値: BOOLEAN overFlag = TRUE: ピクチャーボタンの上で離された
* = FALSE: ピクチャーボタンの外で離された
*/
BOOLEAN checkPctBtn(ComVal *pcv, int num, int no, LPoint lpt)
{
BOOLEAN now, overFlag = TRUE;
Rect rc;
calcPctBtn(num, no, &rc); /* ピクチャーボタンの位置を求める */
if (no == CLOSE) /* クローズボタンか? */
revFillRect(&rc); /* クローズボタンを反転する */
else /* その他のピクチャーボタン */
changePctBtn(pcv, num, no); /* ピクチャーボタンを変更する */
/* マウスの左ボタンが離されるまでループする */
do {
now = GMPtInRect(&rc, EMMSLoc());
if (now != overFlag) {
/* マウスの位置がピクチャーボタン上から変化したら、
ピクチャーボタンを反転/変更する */
if (no == CLOSE) /* クローズボタンか? */
revFillRect(&rc);
else /* その他のピクチャーボタン */
changePctBtn(pcv, num, no);
overFlag = now;
}
} while (EMLStill()); /* 左ボタンが離されたら終わり */
return overFlag;
}
/******************************************************************************
* changePctBtn(): 現在選択中のピクチャーボタンの変更
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* int num サブウィンドウの番号
* int no 今回選択されたピクチャーボタンの番号(0~15)
*/
void changePctBtn(ComVal *pcv, int num, int no)
{
Rect rc;
/* 前回選択されていたピクチャーボタンの位置を求める */
calcPctBtn(num, ((num == TOOL) ? pcv->toolKind : pcv->paletNo), &rc);
revFrameRect(&rc); /* ピクチャーボタンを元に戻す */
/* 今回選択されたピクチャーボタンの位置を求める */
calcPctBtn(num, no, &rc);
revFrameRect(&rc); /* ピクチャーボタンを反転する */
}
/******************************************************************************
* revFillRect(): レクタングルの全面反転
******************************************************************************
* 引数: Rect *prc 反転するレクタングルへのポインタ
*/
void revFillRect(Rect *prc)
{
int lastPM;
lastPM = GMPenMode(G_XOR); /* ペンモードをXORにする */
GMFillRect(prc);
GMPenMode(lastPM); /* ペンモードを元に戻す */
}
/******************************************************************************
* revFrameRect(): レクタングルのフレーム反転
******************************************************************************
* 引数: Rect *prc 反転するレクタングルへのポインタ
*/
void revFrameRect(Rect *prc)
{
int lastPM;
lastPM = GMPenMode(G_XOR); /* ペンモードをXORにする */
GMFrameRect(prc);
GMPenMode(lastPM); /* ペンモードを元に戻す */
}